home *** CD-ROM | disk | FTP | other *** search
- /* SPLINE: function fits splines to data points
- * usage: spline (nodes, iNode, image, width, height,
- * gran, splineType);
- * The cardinal spline (splineType = 2) is an interpolating
- * spline that goes through all points. The B-spline is an
- * approximating spline that may not go through any points,
- * but gives a smoother fit.
- * NOTE that the user must send this function a list of
- * points where the first and last points have been
- * replicated (1st pt, 1st pt, subsequent pts, last pt, last pt).
- */
-
- #include <images.h>
-
- #define INIMAGE(PT1,PT2) (PT1.x >= 0 && PT1.x < imgSize.x \
- && PT1.y >= 0 && PT1.y < imgSize.y \
- && PT2.x >= 0 && PT2.x < imgSize.x \
- && PT2.y >= 0 && PT2.y < imgSize.y)
-
-
- long drawline8 (unsigned char **, struct point, struct point,
- struct point, unsigned char);
- long
- spline (nodes, n, image, imgSize, nT, splineType)
- struct point *nodes; /* list of node coord.s for spline */
- long n; /* total number of node points */
- unsigned char **image; /* image in which to draw spline */
- struct point imgSize; /* size of image */
- long nT; /* granularity of points between nodes */
- short splineType; /* =1 for approx spline; or =2 for interp */
-
- {
- struct point pt1, pt2;
- long nM2; /* number of input pts minus 2 */
- double deltaT;
- double div; /* divisor */
- long i, j;
- double t, t1, t2, t3, t4;
- double xOut, yOut;
-
- deltaT = 1.0 / nT;
- nM2 = n - 2;
- pt1.x = nodes[0].x;
- pt1.y = nodes[0].y;
-
- for (i = 1; i < nM2; i++) {
-
- /* B-spline: cubic approximating spline */
- if (splineType == 1) {
- for (j = 0, t = 0.0; j < nT; j++, t += deltaT) {
- t1 = -t * t * t + 3.0 * t * t - 3.0 * t + 1.0;
- t2 = 3.0 * t * t * t - 6.0 * t * t + 4.0;
- t3 = -3.0 * t * t * t + 3.0 * t * t + 3.0 * t + 1.0;
- t4 = t * t * t;
- div = 6.0;
- xOut = (t1 * (double) nodes[i - 1].x + t2 * (double) nodes[i].x
- + t3 * (double) nodes[i + 1].x + t4 * (double) nodes[i + 2].x)
- / div;
- yOut = (t1 * (double) nodes[i - 1].y + t2 * (double) nodes[i].y
- + t3 * (double) nodes[i + 1].y + t4 * (double) nodes[i + 2].y)
- / div;
- pt2.x = (long) (xOut + 0.5);
- pt2.y = (long) (yOut + 0.5);
- if (INIMAGE (pt1, pt2))
- drawline8 (image, imgSize, pt1, pt2, 0);
- pt1.x = pt2.x;
- pt1.y = pt2.y;
- }
- }
-
- /* cardinal spline: cubic interp. spline */
- else {
- for (j = 0, t = 0.0; j < nT; j++, t += deltaT) {
- t1 = -t * t * t + 2.0 * t * t - t;
- t2 = 3.0 * t * t * t - 5.0 * t * t + 2.0;
- t3 = -3.0 * t * t * t + 4.0 * t * t + t;
- t4 = t * t * t - t * t;
- div = 2.0;
- xOut = (t1 * (double) nodes[i - 1].x + t2 * (double) nodes[i].x
- + t3 * (double) nodes[i + 1].x + t4 * (double) nodes[i + 2].x)
- / div;
- yOut = (t1 * nodes[i - 1].y + t2 * nodes[i].y
- + t3 * nodes[i + 1].y + t4 * nodes[i + 2].y) / div;
- pt2.x = (long) (xOut + 0.5);
- pt2.y = (long) (yOut + 0.5);
- if (INIMAGE (pt1, pt2))
- drawline8 (image, imgSize, pt1, pt2, 0);
- pt1.x = pt2.x;
- pt1.y = pt2.y;
- }
- }
- }
-
- return (0);
- }
-